*
* synthgarch: command to generate GARCH series
* 9/22/23
* command generates y and sigma2 based on inputs. General setup is:
* y = consparam phiparam*l.y + xparam*x - zparam*z + sqrt(sigma2)*epsilon
* sigma2 = ARCH(1) + GARCH(1) + exp(consparam + xparam*x - zparam*z)
*
* Output: saved file "dgp_scenname.dta". We can add
* more if we start to do more w/ the other params
* ------------------------------------------------------------------------

cap prog drop synthgarch
cap program define synthgarch, nclass // nclass b/c all we're doing is storing data
syntax [varlist] [if] [in], time(numlist) garchparam(numlist) ///
 archparam(numlist) xparam(numlist) zparam(numlist) consparam(numlist) ///
 phiparam(numlist) burnin(numlist) seedz(numlist) sims(numlist) ///
 scenname(string) [tdist]

* init blank dataset and scalars
clear
set seed `seedz'
loc tottime = `time' + `burnin' + 1
set obs `tottime'
gen t = _n // +1 b/c of lag
tsset t
gen epsilon = . // not needed in saved dataset
gen sigma2 = . // not needed in saved dataset

* loop across series:
forv i = 1/`sims' {
	
	* what type of error draws?
	if "`tdist'" != "" {
		replace epsilon = rt(2) // Student's t w/ 2 d.f.
	}
	else {
		replace epsilon = rnormal() // normal
	}
	
	* gen IVs
	gen x_`i' = rnormal(0,5)
	gen z_`i' = rbinomial(1,.5)
	
	* init sigma2 and recursively create
	replace sigma2 = exp(rnormal()) in 1 // guess
	replace sigma2 = `archparam'*(l.sigma2*l.epsilon^2) + /// 
		`garchparam'*l.sigma2 + exp(`consparam' + `xparam'*x_`i' + ///
		`zparam'*z_`i') in 2/`tottime'
	
	* init y and recursively create:
	gen y_`i' = `consparam' + `xparam'*x_`i' + `zparam'*z_`i' + ///
	sqrt(sigma2)*epsilon in 1 // guess
	replace y_`i' = `phiparam'*l.y_`i' + `consparam' + `xparam'*x_`i' ///
	+ `zparam'*z_`i' + sqrt(sigma2)*epsilon in 2/`tottime'
}
drop in 1/`burnin'
drop epsilon sigma2
compress
save "dgp_`scenname'.dta", replace
end
